package com.gitee.sidihuo.platform.base;

import lombok.extern.slf4j.Slf4j;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

@Slf4j
public class BaseScheduleFixedDelay {

    protected ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();

    @PostConstruct
    public void init() {
        try {
            log.info("BaseScheduleFixedDelay init begin ");
            Thread thread = new Thread(new Runnable() {
                @Override
                public void run() {
                    //scheduleAtFixedRate 当执行时间 > 频率时间时 在程序结束本次执行后，会立即进行下一次的执行
                    //scheduleWithFixedDelay 是在上一次线程执行结束之后的多长时间执行
                    scheduledExecutorService.scheduleWithFixedDelay(new Runnable() {
                        @Override
                        public void run() {
                            boolean logEnabled = logEnabled();
                            if (logEnabled) {
                                log.info("scheduleWithFixedDelayTask begin ");
                            }
                            try {
                                scheduleWithFixedDelayTask();
                            } catch (Throwable t) {
                                log.warn("scheduleWithFixedDelayTask ", t);
                            }
                            if (logEnabled) {
                                log.info("scheduleWithFixedDelayTask end ");
                            }
                        }
                    }, initialDelay(), period(), timeUnit());
                }
            });
            thread.setName("BaseScheduleFixedDelay");
            thread.start();
            log.info("BaseScheduleFixedDelay init end ");
        } catch (Throwable t) {
            log.warn("BaseScheduleFixedDelay init Throwable ", t);
        }
    }

    protected int initialDelay() {
        return 1;
    }

    protected int period() {
        return 2;
    }

    protected TimeUnit timeUnit() {
        return TimeUnit.MINUTES;
    }

    protected boolean logEnabled() {
        return true;
    }

    protected void scheduleWithFixedDelayTask() {

    }

    @PreDestroy
    public void destroy() {
        try {
            log.info("BaseScheduleFixedDelay destroy ...");
            scheduledExecutorService.shutdown();
            if (!scheduledExecutorService.awaitTermination(10, TimeUnit.SECONDS)) {
                scheduledExecutorService.shutdownNow();
            }
            log.info("BaseScheduleFixedDelay destroy end");
        } catch (InterruptedException e) {
            log.info("BaseScheduleFixedDelay destroy InterruptedException ", e);
            scheduledExecutorService.shutdownNow();
        }
    }


}
